﻿using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Core.Address;
using HslCommunication.Core.Net;
using HslCommunication.Reflection;

namespace HslCommunication.Profinet.GE
{
	/// <summary>
	/// <b>[商业授权]</b> Ge的SRTP协议实现的虚拟PLC，支持I,Q,M,T,SA,SB,SC,S,G的位和字节读写，支持AI,AQ,R的字读写操作，支持读取当前时间及程序名称。<br />
	/// <b>[Authorization]</b> Virtual PLC implemented by Ge's SRTP protocol, supports bit and byte read and write of I, Q, M, T, SA, SB, SC, S, G, 
	/// supports word read and write operations of AI, AQ, R, and supports reading Current time and program name.
	/// </summary>
	/// <remarks>
	/// 实例化之后，直接调用 <see cref="M:HslCommunication.Core.Net.NetworkServerBase.ServerStart(System.Int32)" /> 方法就可以通信及交互，所有的地址都是从1开始的，地址示例：M1,M100, R1，
	/// 具体的用法参考 HslCommunicationDemo 相关界面的源代码。
	/// </remarks>
	/// <example>
	/// 地址的示例，参考 <see cref="T:HslCommunication.Profinet.GE.GeSRTPNet" /> 相关的示例说明
	/// </example>
	// Token: 0x0200009F RID: 159
	public class GeSRTPServer : NetworkDataServerBase
	{
		/// <summary>
		/// 实例化一个默认的对象<br />
		/// Instantiate a default object
		/// </summary>
		// Token: 0x06000BE6 RID: 3046 RVA: 0x00046670 File Offset: 0x00044870
		public GeSRTPServer()
		{
			this.iBuffer = new SoftBuffer(65536);
			this.qBuffer = new SoftBuffer(65536);
			this.mBuffer = new SoftBuffer(65536);
			this.tBuffer = new SoftBuffer(65536);
			this.saBuffer = new SoftBuffer(65536);
			this.sbBuffer = new SoftBuffer(65536);
			this.scBuffer = new SoftBuffer(65536);
			this.sBuffer = new SoftBuffer(65536);
			this.gBuffer = new SoftBuffer(65536);
			this.aiBuffer = new SoftBuffer(131072);
			this.aqBuffer = new SoftBuffer(131072);
			this.rBuffer = new SoftBuffer(131072);
			base.WordLength = 2;
			base.ByteTransform = new RegularByteTransform();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.GE.GeSRTPNet.Read(System.String,System.UInt16)" />
		// Token: 0x06000BE7 RID: 3047 RVA: 0x0004675C File Offset: 0x0004495C
		[HslMqttApi("ReadByteArray", "")]
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			OperateResult<GeSRTPAddress> operateResult = GeSRTPAddress.ParseFrom(address, length, false);
			bool flag = !operateResult.IsSuccess;
			OperateResult<byte[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				result = OperateResult.CreateSuccessResult<byte[]>(this.ReadByCommand(operateResult.Content.DataCode, (ushort)operateResult.Content.AddressStart, operateResult.Content.Length));
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.GE.GeSRTPNet.Write(System.String,System.Byte[])" />
		// Token: 0x06000BE8 RID: 3048 RVA: 0x000467BC File Offset: 0x000449BC
		[HslMqttApi("WriteByteArray", "")]
		public override OperateResult Write(string address, byte[] value)
		{
			OperateResult<GeSRTPAddress> operateResult = GeSRTPAddress.ParseFrom(address, (ushort)value.Length, false);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			else
			{
				result = this.WriteByCommand(operateResult.Content.DataCode, (ushort)operateResult.Content.AddressStart, operateResult.Content.Length, value);
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.GE.GeSRTPNet.ReadBool(System.String,System.UInt16)" />
		// Token: 0x06000BE9 RID: 3049 RVA: 0x0004681C File Offset: 0x00044A1C
		[HslMqttApi("ReadBoolArray", "")]
		public override OperateResult<bool[]> ReadBool(string address, ushort length)
		{
			OperateResult<GeSRTPAddress> operateResult = GeSRTPAddress.ParseFrom(address, length, true);
			bool flag = !operateResult.IsSuccess;
			OperateResult<bool[]> result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			else
			{
				bool flag2;
				result = OperateResult.CreateSuccessResult<bool[]>(this.GetSoftBufferFromDataCode(operateResult.Content.DataCode, out flag2).GetBool(operateResult.Content.AddressStart, (int)length));
			}
			return result;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.GE.GeSRTPNet.Write(System.String,System.Boolean[])" />
		// Token: 0x06000BEA RID: 3050 RVA: 0x00046878 File Offset: 0x00044A78
		[HslMqttApi("WriteBoolArray", "")]
		public override OperateResult Write(string address, bool[] value)
		{
			OperateResult<GeSRTPAddress> operateResult = GeSRTPAddress.ParseFrom(address, (ushort)value.Length, true);
			bool flag = !operateResult.IsSuccess;
			OperateResult result;
			if (flag)
			{
				result = OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			else
			{
				bool flag2;
				this.GetSoftBufferFromDataCode(operateResult.Content.DataCode, out flag2).SetBool(value, operateResult.Content.AddressStart);
				result = OperateResult.CreateSuccessResult();
			}
			return result;
		}

		/// <inheritdoc />
		// Token: 0x06000BEB RID: 3051 RVA: 0x000468D8 File Offset: 0x00044AD8
		[DebuggerStepThrough]
		protected override void ThreadPoolLoginAfterClientCheck(Socket socket, IPEndPoint endPoint)
		{
			GeSRTPServer.<ThreadPoolLoginAfterClientCheck>d__5 <ThreadPoolLoginAfterClientCheck>d__ = new GeSRTPServer.<ThreadPoolLoginAfterClientCheck>d__5();
			<ThreadPoolLoginAfterClientCheck>d__.<>t__builder = AsyncVoidMethodBuilder.Create();
			<ThreadPoolLoginAfterClientCheck>d__.<>4__this = this;
			<ThreadPoolLoginAfterClientCheck>d__.socket = socket;
			<ThreadPoolLoginAfterClientCheck>d__.endPoint = endPoint;
			<ThreadPoolLoginAfterClientCheck>d__.<>1__state = -1;
			<ThreadPoolLoginAfterClientCheck>d__.<>t__builder.Start<GeSRTPServer.<ThreadPoolLoginAfterClientCheck>d__5>(ref <ThreadPoolLoginAfterClientCheck>d__);
		}

		// Token: 0x06000BEC RID: 3052 RVA: 0x00046920 File Offset: 0x00044B20
		[DebuggerStepThrough]
		private void SocketAsyncCallBack(IAsyncResult ar)
		{
			GeSRTPServer.<SocketAsyncCallBack>d__6 <SocketAsyncCallBack>d__ = new GeSRTPServer.<SocketAsyncCallBack>d__6();
			<SocketAsyncCallBack>d__.<>t__builder = AsyncVoidMethodBuilder.Create();
			<SocketAsyncCallBack>d__.<>4__this = this;
			<SocketAsyncCallBack>d__.ar = ar;
			<SocketAsyncCallBack>d__.<>1__state = -1;
			<SocketAsyncCallBack>d__.<>t__builder.Start<GeSRTPServer.<SocketAsyncCallBack>d__6>(ref <SocketAsyncCallBack>d__);
		}

		// Token: 0x06000BED RID: 3053 RVA: 0x00046960 File Offset: 0x00044B60
		private SoftBuffer GetSoftBufferFromDataCode(byte code, out bool isBit)
		{
			if (code <= 30)
			{
				switch (code)
				{
				case 8:
					isBit = false;
					return this.rBuffer;
				case 9:
				case 11:
					break;
				case 10:
					isBit = false;
					return this.aiBuffer;
				case 12:
					isBit = false;
					return this.aqBuffer;
				default:
					if (code == 16)
					{
						isBit = false;
						return this.iBuffer;
					}
					switch (code)
					{
					case 20:
						isBit = false;
						return this.tBuffer;
					case 22:
						isBit = false;
						return this.mBuffer;
					case 24:
						isBit = false;
						return this.saBuffer;
					case 26:
						isBit = false;
						return this.sbBuffer;
					case 28:
						isBit = false;
						return this.scBuffer;
					case 30:
						isBit = false;
						return this.tBuffer;
					}
					break;
				}
			}
			else
			{
				if (code == 56)
				{
					isBit = false;
					return this.gBuffer;
				}
				if (code == 66)
				{
					isBit = false;
					return this.qBuffer;
				}
				switch (code)
				{
				case 70:
					isBit = true;
					return this.iBuffer;
				case 72:
					isBit = true;
					return this.qBuffer;
				case 74:
					isBit = true;
					return this.tBuffer;
				case 76:
					isBit = true;
					return this.mBuffer;
				case 78:
					isBit = true;
					return this.saBuffer;
				case 80:
					isBit = true;
					return this.sbBuffer;
				case 82:
					isBit = true;
					return this.scBuffer;
				case 84:
					isBit = true;
					return this.tBuffer;
				case 86:
					isBit = true;
					return this.gBuffer;
				}
			}
			isBit = false;
			return null;
		}

		// Token: 0x06000BEE RID: 3054 RVA: 0x00046B64 File Offset: 0x00044D64
		private byte[] ReadByCommand(byte dataCode, ushort address, ushort length)
		{
			bool flag;
			SoftBuffer softBufferFromDataCode = this.GetSoftBufferFromDataCode(dataCode, out flag);
			bool flag2 = softBufferFromDataCode == null;
			byte[] result;
			if (flag2)
			{
				result = null;
			}
			else
			{
				bool flag3 = flag;
				if (flag3)
				{
					int num;
					ushort length2;
					int num2;
					HslHelper.CalculateStartBitIndexAndLength((int)address, length, out num, out length2, out num2);
					result = softBufferFromDataCode.GetBytes(num / 8, (int)length2);
				}
				else
				{
					bool flag4 = dataCode == 10 || dataCode == 12 || dataCode == 8;
					if (flag4)
					{
						result = softBufferFromDataCode.GetBytes((int)(address * 2), (int)(length * 2));
					}
					else
					{
						result = softBufferFromDataCode.GetBytes((int)address, (int)length);
					}
				}
			}
			return result;
		}

		// Token: 0x06000BEF RID: 3055 RVA: 0x00046BE4 File Offset: 0x00044DE4
		private byte[] ReadByCommand(byte[] command)
		{
			byte[] array = this.ReadByCommand(command[43], BitConverter.ToUInt16(command, 44), BitConverter.ToUInt16(command, 46));
			bool flag = array == null;
			byte[] result;
			if (flag)
			{
				result = null;
			}
			else
			{
				bool flag2 = array.Length < 7;
				if (flag2)
				{
					byte[] array2 = "\r\n03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00\r\n00 01 00 00 00 00 00 00 00 00 00 00 00 00 06 d4\r\n00 0e 00 00 00 60 01 a0 01 01 00 00 00 00 00 00\r\n00 00 ff 02 03 00 5c 01".ToHexBytes();
					array.CopyTo(array2, 44);
					command.SelectMiddle(2, 2).CopyTo(array2, 2);
					result = array2;
				}
				else
				{
					byte[] array3 = new byte[56 + array.Length];
					"03 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 06 94\r\n\t\t\t\t00 0e 00 00 00 60 01 a0 00 00 0c 00 00 18 00 00 01 01 ff 02 03 00 5c 01".ToHexBytes().CopyTo(array3, 0);
					command.SelectMiddle(2, 2).CopyTo(array3, 2);
					array.CopyTo(array3, 56);
					BitConverter.GetBytes((ushort)array.Length).CopyTo(array3, 4);
					result = array3;
				}
			}
			return result;
		}

		// Token: 0x06000BF0 RID: 3056 RVA: 0x00046CAC File Offset: 0x00044EAC
		private OperateResult WriteByCommand(byte dataCode, ushort address, ushort length, byte[] value)
		{
			bool flag;
			SoftBuffer softBufferFromDataCode = this.GetSoftBufferFromDataCode(dataCode, out flag);
			bool flag2 = softBufferFromDataCode == null;
			OperateResult result;
			if (flag2)
			{
				result = new OperateResult(StringResources.Language.NotSupportedDataType);
			}
			else
			{
				bool flag3 = flag;
				if (flag3)
				{
					int num;
					ushort num2;
					int num3;
					HslHelper.CalculateStartBitIndexAndLength((int)address, length, out num, out num2, out num3);
					softBufferFromDataCode.SetBool(value.ToBoolArray().SelectMiddle((int)(address % 8), (int)length), (int)address);
				}
				else
				{
					bool flag4 = dataCode == 10 || dataCode == 12 || dataCode == 8;
					if (flag4)
					{
						bool flag5 = value.Length % 2 == 1;
						if (flag5)
						{
							return new OperateResult(StringResources.Language.GeSRTPWriteLengthMustBeEven);
						}
						softBufferFromDataCode.SetBytes(value, (int)(address * 2));
					}
					else
					{
						softBufferFromDataCode.SetBytes(value, (int)address);
					}
				}
				result = OperateResult.CreateSuccessResult();
			}
			return result;
		}

		// Token: 0x06000BF1 RID: 3057 RVA: 0x00046D70 File Offset: 0x00044F70
		private byte[] WriteByCommand(byte[] command)
		{
			OperateResult operateResult = this.WriteByCommand(command[51], BitConverter.ToUInt16(command, 52), BitConverter.ToUInt16(command, 54), command.RemoveBegin(56));
			bool flag = !operateResult.IsSuccess;
			byte[] result;
			if (flag)
			{
				result = null;
			}
			else
			{
				byte[] array = "03 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00\r\n00 02 00 00 00 00 00 00 00 00 00 00 00 00 09 d4\r\n00 0e 00 00 00 60 01 a0 01 01 00 00 00 00 00 00\r\n00 00 ff 02 03 00 5c 01".ToHexBytes();
				command.SelectMiddle(2, 2).CopyTo(array, 2);
				result = array;
			}
			return result;
		}

		// Token: 0x06000BF2 RID: 3058 RVA: 0x00046DD4 File Offset: 0x00044FD4
		private byte[] ReadDateTimeByCommand(byte[] command)
		{
			byte[] array = "03 00 03 00 07 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 06 94\r\n\t\t\t\t00 0e 00 00 00 60 01 a0 00 00 0c 00 00 18 00 00 01 01 ff 02 03 00 5c 01 00 00 00 00 00 00 03".ToHexBytes();
			DateTime now = DateTime.Now;
			now.Second.ToString("D2").ToHexBytes().CopyTo(array, 56);
			now.Minute.ToString("D2").ToHexBytes().CopyTo(array, 57);
			now.Hour.ToString("D2").ToHexBytes().CopyTo(array, 58);
			now.Day.ToString("D2").ToHexBytes().CopyTo(array, 59);
			now.Month.ToString("D2").ToHexBytes().CopyTo(array, 60);
			(now.Year - 2000).ToString("D2").ToHexBytes().CopyTo(array, 61);
			command.SelectMiddle(2, 2).CopyTo(array, 2);
			return array;
		}

		// Token: 0x06000BF3 RID: 3059 RVA: 0x00046EDC File Offset: 0x000450DC
		private byte[] ReadProgramNameByCommand(byte[] command)
		{
			byte[] array = "\r\n03 00 07 00 2a 00 00 00 00 00 00 00 00 00 00 00 \r\n00 01 00 00 00 00 00 00 00 00 00 00 00 00 06 94 \r\n00 0e 00 00 00 62 01 a0 00 00 2a 00 00 18 00 00 \r\n01 01 ff 02 03 00 5c 01 00 00 00 00 00 00 00 00 \r\n01 00 00 00 00 00 00 00 00 00 50 41 43 34 30 30 \r\n00 00 00 00 00 00 00 00 00 00 03 00 01 50 05 18 \r\n01 21".ToHexBytes();
			command.SelectMiddle(2, 2).CopyTo(array, 2);
			return array;
		}

		/// <inheritdoc />
		// Token: 0x06000BF4 RID: 3060 RVA: 0x00046F0C File Offset: 0x0004510C
		protected override void LoadFromBytes(byte[] content)
		{
			bool flag = content.Length < 983040;
			if (flag)
			{
				throw new Exception("File is not correct");
			}
			this.iBuffer.SetBytes(content, 0, 0, 65536);
			this.qBuffer.SetBytes(content, 65536, 0, 65536);
			this.mBuffer.SetBytes(content, 131072, 0, 65536);
			this.tBuffer.SetBytes(content, 196608, 0, 65536);
			this.saBuffer.SetBytes(content, 262144, 0, 65536);
			this.sbBuffer.SetBytes(content, 327680, 0, 65536);
			this.scBuffer.SetBytes(content, 393216, 0, 65536);
			this.sBuffer.SetBytes(content, 458752, 0, 65536);
			this.gBuffer.SetBytes(content, 524288, 0, 65536);
			this.aiBuffer.SetBytes(content, 589824, 0, 131072);
			this.aqBuffer.SetBytes(content, 720896, 0, 131072);
			this.rBuffer.SetBytes(content, 851968, 0, 131072);
		}

		/// <inheritdoc />
		// Token: 0x06000BF5 RID: 3061 RVA: 0x00047050 File Offset: 0x00045250
		protected override byte[] SaveToBytes()
		{
			byte[] array = new byte[983040];
			Array.Copy(this.iBuffer.GetBytes(), 0, array, 0, 65536);
			Array.Copy(this.qBuffer.GetBytes(), 0, array, 65536, 65536);
			Array.Copy(this.mBuffer.GetBytes(), 0, array, 131072, 65536);
			Array.Copy(this.tBuffer.GetBytes(), 0, array, 196608, 65536);
			Array.Copy(this.saBuffer.GetBytes(), 0, array, 262144, 65536);
			Array.Copy(this.sbBuffer.GetBytes(), 0, array, 327680, 65536);
			Array.Copy(this.scBuffer.GetBytes(), 0, array, 393216, 65536);
			Array.Copy(this.sBuffer.GetBytes(), 0, array, 458752, 65536);
			Array.Copy(this.gBuffer.GetBytes(), 0, array, 524288, 65536);
			Array.Copy(this.aiBuffer.GetBytes(), 0, array, 589824, 131072);
			Array.Copy(this.aqBuffer.GetBytes(), 0, array, 720896, 131072);
			Array.Copy(this.rBuffer.GetBytes(), 0, array, 851968, 131072);
			return array;
		}

		/// <inheritdoc />
		// Token: 0x06000BF6 RID: 3062 RVA: 0x000471C8 File Offset: 0x000453C8
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				this.iBuffer.Dispose();
				this.qBuffer.Dispose();
				this.mBuffer.Dispose();
				this.tBuffer.Dispose();
				this.saBuffer.Dispose();
				this.sbBuffer.Dispose();
				this.scBuffer.Dispose();
				this.sBuffer.Dispose();
				this.gBuffer.Dispose();
				this.aiBuffer.Dispose();
				this.aqBuffer.Dispose();
				this.rBuffer.Dispose();
			}
			base.Dispose(disposing);
		}

		/// <inheritdoc />
		// Token: 0x06000BF7 RID: 3063 RVA: 0x00047278 File Offset: 0x00045478
		public override string ToString()
		{
			return string.Format("GeSRTPServer[{0}]", base.Port);
		}

		// Token: 0x0400032F RID: 815
		private SoftBuffer iBuffer;

		// Token: 0x04000330 RID: 816
		private SoftBuffer qBuffer;

		// Token: 0x04000331 RID: 817
		private SoftBuffer mBuffer;

		// Token: 0x04000332 RID: 818
		private SoftBuffer tBuffer;

		// Token: 0x04000333 RID: 819
		private SoftBuffer saBuffer;

		// Token: 0x04000334 RID: 820
		private SoftBuffer sbBuffer;

		// Token: 0x04000335 RID: 821
		private SoftBuffer scBuffer;

		// Token: 0x04000336 RID: 822
		private SoftBuffer sBuffer;

		// Token: 0x04000337 RID: 823
		private SoftBuffer gBuffer;

		// Token: 0x04000338 RID: 824
		private SoftBuffer aiBuffer;

		// Token: 0x04000339 RID: 825
		private SoftBuffer aqBuffer;

		// Token: 0x0400033A RID: 826
		private SoftBuffer rBuffer;

		// Token: 0x0400033B RID: 827
		private const int DataPoolLength = 65536;
	}
}
